package com.springboot.demo.utils;

/**
 * @author wubc683
 * @desc 对称加密
 * @date 2021-10-18 11:24
 */

import org.springframework.security.crypto.codec.Utf8;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.util.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class AESEncryptUtil {

    //KeyGenerator 提供对称密钥生成器的功能，支持各种算法
    private KeyGenerator keygen;
    //SecretKey 负责保存对称密钥
    private SecretKey deskey;
    //Cipher负责完成加密或解密工作
    private Cipher c;
    //该字节数组负责保存加密的结果
    private byte[] cipherByte;
    // 默认的初始化向量值
    private static final String IV_DEFAULT = "0123456789abcdef";
    // 默认加密的KEY
    private static final String KEY_DEFAULT = "8G5M4Ff9hel8fUA9";

//    public AESEncryptUtil() throws NoSuchAlgorithmException, NoSuchPaddingException {
//        Security.addProvider(new com.sun.crypto.provider.SunJCE());
//        //实例化支持DES算法的密钥生成器(算法名称命名需按规定，否则抛出异常)
//        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
//        keygen = KeyGenerator.getInstance("AES");
//        //生成密钥
//        deskey = keygen.generateKey();
//        //生成Cipher对象,指定其支持的DES算法
//        c = Cipher.getInstance("AES");
//    }

    /**
     * 对字符串加密
     *
     * @param str
     * @return: byte[]
     */
    public static String Encrytor(String str) throws InvalidKeyException,
            IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException, NoSuchAlgorithmException {
//        // 根据密钥，对Cipher对象进行初始化，ENCRYPT_MODE表示加密模式
//        c.init(Cipher.ENCRYPT_MODE, deskey);
//        // 加密，结果保存进cipherByte
//        byte[] bytes = c.doFinal(str.getBytes(StandardCharsets.UTF_8));
//        // base64加密
//        BASE64Encoder base64Encoder = new BASE64Encoder();
//        cipherByte = base64Encoder.encode(bytes).getBytes(StandardCharsets.UTF_8);
//        return new String(cipherByte);
        byte[] raw = KEY_DEFAULT.getBytes(StandardCharsets.UTF_8);
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//"算法/模式/补码方式"
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(str.getBytes(StandardCharsets.UTF_8));
        //此处使用BASE64做转码功能，同时能起到2次加密的作用。
        return new BASE64Encoder().encode(encrypted);
    }

    /**
     * 对字符串解密
     *
     * @param str
     * @return: byte[]
     */
    public static String Decryptor(String str) throws InvalidKeyException,
            IllegalBlockSizeException, BadPaddingException, IOException, NoSuchPaddingException, NoSuchAlgorithmException {
//        // base64解密
//        BASE64Decoder base64Decoder = new BASE64Decoder();
//        byte[] bytes = base64Decoder.decodeBuffer(str);
//        // 根据密钥，对Cipher对象进行初始化，DECRYPT_MODE表示加密模式
//        c.init(Cipher.DECRYPT_MODE, deskey);
//        cipherByte = c.doFinal(bytes);
//        return new String(cipherByte);
        byte[] raw = KEY_DEFAULT.getBytes(StandardCharsets.UTF_8);
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] bytes = new BASE64Decoder().decodeBuffer(str);//先用base64解密
        byte[] original = cipher.doFinal(bytes);
        return new String(original, StandardCharsets.UTF_8);
    }
}
